home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / os2 / cenvi2.arj / CMMTUTOR.DOC < prev    next >
Text File  |  1993-12-21  |  51KB  |  1,175 lines

  1.                     CEnvi Shareware Manual, Chapter 2:
  2.                            Cmm Language Tutorial
  3.  
  4.  
  5.                      CEnvi unregistered version 1.008
  6.                              21 December 1993
  7.  
  8.                        CEnvi Shareware User's Manual
  9.  
  10.           Copyright 1993, Nombas, All Rights Reserved.
  11.           Published by Nombas, P.O. Box 875, Medford, MA 02155 USA
  12.           (617)391-6595
  13.  
  14.           Thank you for trying this shareware version of CEnvi from Nombas,
  15.           a member of the Association of Shareware Professionals (ASP).
  16.  
  17. 2.  The Cmm Language: Tutorial for Non-C Programmers
  18.  
  19.           The information in this chapter is geared toward those who are
  20.           not familiar with the C programming language.  C programmers
  21.           should jump ahead to the next chapter: Cmm versus C.  This
  22.           section is an introduction to and description of the Cmm
  23.           programming language.
  24.  
  25.           If you can write a batch, script, or macro file, or if you can
  26.           remember what "y = x + 1" means from your algebra class, then
  27.           you're ready to take on Cmm.  Really.  Cmm contains only
  28.           variables, mathematics symbols (remember algebra), and these few
  29.           statements: IF, ELSE, DO, WHILE, FOR, SWITCH, CASE, BREAK,
  30.           DEFAULT, CONTINUE, GOTO, and RETURN.
  31.  
  32.           This section is an abbreviation of the Cmm Language Tutorial
  33.           chapter in the CEnvi registered manual.  The CEnvi registered
  34.           manual goes into much more depth, has many more examples, and
  35.           follows a step-by-step tutorial to create a simple text editor
  36.           with CEnvi.
  37.  
  38. 2.1.  Your first Cmm program
  39.  
  40.           Before going into a description of Cmm, let's first make sure
  41.           that CEnvi is working properly.  With a text editor (e.g., EDIT
  42.           for DOS, E for OS/2, or NOTEPAD for Windows) create the file
  43.           HELLO.CMM and enter this text:
  44.  
  45.               // Hello.cmm: My first Cmm program
  46.               Count = 1; /* Count is how many Cmm programs I've written */
  47.               printf("Hello world. This is my %dst Cmm program.\n",Count);
  48.               printf("Press any key to quit...");
  49.               getch();
  50.  
  51.           You have now written a Cmm program named "HELLO.CMM".  Don't be
  52.           concerned if you do not yet understand the HELLO.CMM program; it
  53.           should become clear as Cmm is defined.  Now execute this program
  54.           (for DOS or OS/2 you would enter "CENVI HELLO.CMM" and for
  55.           Windows you need may use the File Manager and double-click on the
  56.           file name).  You should get this output:
  57.  
  58.               Hello world. This is my 1st Cmm program.
  59.               Press any key to quit...
  60.  
  61.           If this program will execute, then you are ready to go on to
  62.           learn about Cmm.  If it did not execute then consult the CEnvi
  63.           installation section in the first chapter of this shareware
  64.           manual.
  65.  
  66. 2.2.  Cmm comments
  67.  
  68.           Comments are used in Cmm code to explain what the code does, but
  69.           the comment itself does nothing.  Comments are very useful in
  70.           programming.  A comment takes nothing away from the execution of
  71.           a program, but adds immeasurably to the readability of the source
  72.           code.
  73.  
  74.           In Cmm, any text on a line following two slash characters (//) is
  75.           considered a comment and so is ignored by the Cmm interpreter.
  76.           Likewise, anything between a slash-asterisk (/*) and an
  77.           asterisk-slash (*/) is a comment (this type of comment may extend
  78.           over many lines).  In the HELLO.CMM program there is a "//"
  79.           comment on the first line and a "/* blah blah */" comment on the
  80.           second line.
  81.  
  82. 2.3.  Cmm primary data types
  83.  
  84.           There are three principal data types in Cmm:
  85.             *Byte: A character (e.g., 'D') or a whole number between 0 and
  86.               255, inclusive
  87.             *Integer: A whole number value; this is the most common numeric
  88.               data type (examples: 0, -1000, 567, 4335600)
  89.             *Float: floating point numbers; any number containing a decimal
  90.               point (examples: 0.567, 3.14159, -5.456e-12)
  91.  
  92.           Cmm determines the data type of a number by how it is used; for
  93.           example, in the HELLO.CMM program the "1" in the second line is
  94.           an integer because that is the default type for numbers without a
  95.           decimal point.
  96.  
  97. 2.3.1   Escape Sequences for Characters
  98.  
  99.           Certain characters are represented with a multi-character
  100.           sequence beginning with a backslash (\).  These are called escape
  101.           sequences, and have the following meanings:
  102.               \a      Audible bell
  103.               \b      Backspace
  104.               \f      Formfeed
  105.               \n      Newline
  106.               \r      Carriage return
  107.               \t      Tab
  108.               \v      Vertical tab
  109.               \'      Single quote
  110.               \"      Double quote
  111.               \\      Backslash character
  112.               \###    Octal number  // ex: '\033' is escape character
  113.                                     // ex: \0 is null character
  114.               \x##    Hex number    // '\x1B' is escape character
  115.  
  116. 2.4.  Cmm Variables
  117.  
  118.           A Cmm variable is a symbol that may be assigned data.  The
  119.           assignment of data is usually performed by the equal sign (=), as
  120.           in the line "Count = 1" in HELLO.CMM.  After variables have been
  121.           assigned, they can be treated as their data type.  So, after
  122.           these statements:
  123.               Count = 1               // assign count as the integer 1
  124.               Count = Count + 2       // same as: Count = 1 + 2
  125.           Count would now have the value 3.
  126.  
  127. 2.5.  Cmm Expressions, Statements, and Blocks
  128.  
  129.           A Cmm "expression" or "statement" is any sequence of code that
  130.           perform a computation or take an action (e.g., "Count=1",
  131.           "(2+4)*3").  Cmm code is executed one statement at a time in the
  132.           order it is read.  A Cmm program is a series of statements
  133.           executed sequentially, one at a time.  Each line of HELLO.CMM,
  134.           for example, follows the previous line as it is written and as it
  135.           is executed.
  136.  
  137.           A statement usually ends in a semicolon (;) (this is required in
  138.           C, and still a good idea in Cmm to improve readability).  Each
  139.           program statement is usually written on a separate line to make
  140.           the code easy to read.
  141.  
  142.           Expressions may be grouped to effect the sequence of processing;
  143.           expressions inside parentheses are processed first.  Notice that:
  144.               4 * 7 - 5 * 3       // 28 - 14 = 13
  145.           has the same meaning, do to algebraic operator precedence, as:
  146.               (4 * 7) - (5 * 3)   // 28 - 15 = 13
  147.           but has a different meaning than:
  148.               4 * (7 - 5) * 3     // 4 * 2 * 3 = 8 * 3 = 24
  149.           which is still different from:
  150.               4 * (7 - (5 * 3))   // 4 * (7 - 15) = 4 * -8 = -32
  151.  
  152.           A "block" is a group of statements enclosed in curly braces ({})
  153.           to show that they are all a group and so are treated as one
  154.           statement.  For example, HELLO.CMM may be rewritten as:
  155.               // Hello.cmm: My first Cmm program
  156.               Count = 1; /* Count is how many Cmm programs I've written */
  157.               printf("Hello world. This is my %dst Cmm program.\n",Count);
  158.               {
  159.                 // this block tells the user we're done, and quits
  160.                 printf("Press any key to quit...");
  161.                 getch();
  162.               }
  163.           The indentation of statements is not necessary, but is useful for
  164.           readability.
  165.  
  166. 2.6.  Cmm Mathematical Operators
  167.  
  168.           Cmm code usually contains some mathematical operations, such as
  169.           adding numbers together, multiplying, dividing, etc.  These are
  170.           written in a natural way, such as "2 + 3" when you want to add
  171.           two and three.  The next few subsections define the recognized
  172.           operators within the comments of sample code:
  173.  
  174. 2.6.1   Basic Arithmetic
  175.  
  176.               //  "="  assignment: sets a variable's value
  177.               i = 2;      // i is 2
  178.  
  179.               //  "+"  addition: adds two numbers
  180.               i = i + 3;  // i is now (2+3) or 5
  181.  
  182.               //  "-"  subtraction: subtracts a number
  183.               i = i - 3;  // i is now (5-3) or 2 again
  184.  
  185.               //  "*"  multiplication:
  186.               i = i * 5;  // i is now (2*5) or 10
  187.  
  188.               //  "/"  division:
  189.               i = i / 3;  // i is now (10/3) or 3 (no remainder)
  190.  
  191.               //  "%"  remainder: remainder after division
  192.               i = 10;
  193.               i = i % 3;  // i is now (10%3) or 1
  194.  
  195. 2.6.2   Assignment Arithmetic
  196.  
  197.           Each of the above operators can combined with the assignment
  198.           operator (=) as a shortcut.  This automatically assumes that the
  199.           assigned variable is the first variable in the arithmetic
  200.           operation.  Using assignment arithmetic operators, the above code
  201.           could be simplified as follows:
  202.  
  203.               //  "="  assignment: sets a variable's value
  204.               i = 2;      // i is 2
  205.  
  206.               //  "+="  assign addition: adds number
  207.               i += 3;     // i is now (2+3) or 5
  208.  
  209.               //  "-="  assign subtraction: subtracts a number
  210.               i -= 3;     // i is now (5-3) or 2 again
  211.  
  212.               //  "*="  assign multiplication:
  213.               i *= 5;     // i is now (2*5) or 10
  214.  
  215.               //  "/="  assign divide:
  216.               i /= 3;     // i is now (10/3) or 3 (no remainder)
  217.  
  218.               //  "%="  assign remainder: remainder after division
  219.               i = 10;
  220.               i %= i % 3; // i is now (10%3) or 1
  221.  
  222. 2.6.3   Auto-Increment (++) and Auto-Decrement (--)
  223.  
  224.           Other arithmetic shortcuts are the auto-increment (++) and
  225.           auto-decrement (--) operators.  These operators add or subtract 1
  226.           (one) from the value to which they are applied.  ("i++" is a
  227.           shortcut for "i+=1", which is itself shortcut for "i=i+1").
  228.           These operators can be used before (prefix) or after (postfix)
  229.           their variables.  If used before, then the variable is altered
  230.           before it is used in the statement; if used after, then the
  231.           variable is altered after it is used in the statement.  This is
  232.           demonstrated by the following code sequence:
  233.  
  234.               i = 4;    // i is initialized to 4
  235.               j = ++i;  // j is 5, i is 5 (i was incremented before use)
  236.               j = i++;  // j is 5, i is 6 (i was incremented after use)
  237.               j = --i;  // j is 5, i is 5 (i was decremented before use)
  238.               j = i--;  // j is 5, i is 4 (i was decremented after use)
  239.  
  240. 2.7.  Cmm Arrays and Strings
  241.  
  242.           An "array" is a group of individual data elements.  Each
  243.           individual item in the array is then called an "array element".
  244.           An element of an array is itself a variable, much like any other
  245.           variable.  Any particular element of the array is selected by
  246.           specifying the element's offset in the array.  This offset is an
  247.           integer in square brackets ([]).  For example:
  248.  
  249.               prime[0] = 2;
  250.               prime[1] = 3;
  251.               prime[2] = 5;
  252.               month[0] = "January";
  253.               month[1] = "February";
  254.               month[2] = "March";
  255.  
  256.           An array in Cmm does not need to be pre-defined for size or data
  257.           type, as it does in other languages.  Any array extends from
  258.           minus infinity to plus infinity (within reasonable computer
  259.           memory limits).  The data type for the array is the type of the
  260.           data first assigned to it.
  261.  
  262.           If Cmm code begins with:
  263.               foo[5] = 7;
  264.               foo[2] = -100;
  265.               foo[-5] = 4;
  266.           then foo is an array of integers and the element at index 7 is a
  267.           5, at index 2 is -100, and at index -5 is 4.  "foo[5]" can be
  268.           used in the code anywhere that a variable could be used.
  269.  
  270. 2.7.1   Array Initialization
  271.  
  272.           Arrays can be initialized by initializing specific elements, as
  273.           in:
  274.               foo[5] = 7; foo[2] = -100; foo[-5] = 4;
  275.           or by enclosing all the initial statements in curly braces, which
  276.           will cause the array to start initializing at element 0, as in:
  277.               foo = { 0, 0, -100, 0, 0, 7 };
  278.  
  279. 2.7.2   Strings
  280.  
  281.           Strings are arrays of bytes that end in the null-byte (zero).
  282.           "String" is just a shorthand way to specify this array of bytes.
  283.           A string is most commonly specified simply by writing text within
  284.           two quote characters (e.g., "I am a string.")
  285.  
  286.           If this statement were present in the Cmm code:
  287.               animal = "dog";
  288.           it would be identical to this statement:
  289.               animal = { 'd', 'o', 'g', 0 };
  290.           and in both cases the value at animal[0] is 'd', at animal[2] is
  291.           'g', and at animal[3] is 0.
  292.  
  293.           Escape sequences encountered in strings will be translated into
  294.           their byte value.  So you'll often see strings such as "\aHello
  295.           world\n" where the "\a" means to beep and the "\n" means to put a
  296.           newline character at the end of the string.  Cmm provides the
  297.           back-quote (`), also known as known as the "back-tick" or "grave
  298.           accent", as an alternative quote character to indicate that
  299.           escape sequences are not to be translated.  So, for example, here
  300.           are two ways to describe the same file name:
  301.               "c:\\autoexec.bat"  // traditional method
  302.               `c:\autoexec.bat`   // alternative method
  303.  
  304. 2.7.3   Array Arithmetic
  305.  
  306.           When one array is assigned to the other, as in:
  307.               foo = "cat";
  308.               goo = foo;
  309.           then both variables define the same array and start at the same
  310.           offset 0.  In this case, if foo[2] is changed then you will find
  311.           that goo[2] has also been changed.
  312.  
  313.           Integer addition and subtraction can also be performed on arrays.
  314.           Array addition or subtraction sets where the array is based.  By
  315.           altering the previous code segment to:
  316.               foo = "cat";
  317.               goo = foo + 1;
  318.           goo and foo would now be arrays containing the same data, except
  319.           that now goo is based one element further, and foo[2] is now the
  320.           same data as goo[1].
  321.  
  322.           To demonstrate:
  323.               foo = "cat";  // foo[0] is 'c', foo[1] = 'a'
  324.               goo = foo + 1;// goo[0] is 'a', goo[-1] = 'c'
  325.               goo[0] = 'u'; // goo[0] is 'u', foo[1] = 'u', foo is "cut"
  326.               goo++;        // goo[0] is 't', goo[-2] = 'c'
  327.               goo[-2] = 'b' // goo[0] is 't', foo[0] = 'b', foo is "but"
  328.  
  329. 2.7.4   Multi-Dimensional Arrays: Arrays of Arrays
  330.  
  331.           An array element is a variable, and so if the type of that
  332.           element's variable is itself an array, then you have an array of
  333.           arrays.  A statement such as:
  334.               goo[4][2] = 5;
  335.           indicates that goo is an array of arrays, and that element 2 of
  336.           element 4 is the integer 5.
  337.  
  338.           Multi-dimensional arrays might be useful for programming a
  339.           tic-tac-toe game.  Each row and column of the 3x3 board could be
  340.           represented with a row, column element containing 'X', 'O' or ' '
  341.           (blank) depending on the character at that location.  For
  342.           example, a horizontal 'X' win in the middle row could be
  343.           initialized like this:
  344.               board[1][0] = 'X';
  345.               board[1][1] = 'X';
  346.               board[1][2] = 'X';
  347.  
  348.           Note that a string is an array, and so anytime you make an array
  349.           of strings you are defining an array of arrays.
  350.  
  351. 2.8.  Cmm Structures
  352.  
  353.           A "structure" is a collection of named variables that belong
  354.           together as a whole.  Each of the named variables in a structure
  355.           is called a member of that structure and can be any data type
  356.           (integer, float, array, another structure, array of structures,
  357.           etc.).  These structure members are associated with the structure
  358.           by using a period between the structure variable and the member
  359.           name.
  360.  
  361.           A simple and useful example of a structure is to specify a point
  362.           on the screen.  A point is made up of a row and column, and so
  363.           you may specify:
  364.               place.row = 12;   // set to row 12
  365.               place.col = 20;   // set at column 20
  366.               place.row--;      // move up one row to row 11
  367.  
  368.           Two structures can be compared for equality or inequality, and
  369.           they may be assigned, but no other arithmetic operations can be
  370.           performed on a structure.
  371.  
  372. 2.9.  printf() and getch()
  373.  
  374.           Although although the Cmm "function" has not yet been defined, it
  375.           is useful to use two functions already, printf() and getch(), for
  376.           learning more about Cmm programming.  Unfortunately, printf() is
  377.           about as complicated as a function can get.
  378.  
  379. 2.9.1   printf() Syntax
  380.  
  381.           printf() prints to the screen, providing useful feedback on your
  382.           programming.  The basic syntax of printf() is this:
  383.  
  384.               printf(FormatString,data1,data2,data3,...);
  385.  
  386.           FormatString is the string that will be printed to the screen.
  387.           When FormatString contains a percent character (%) followed by
  388.           another character, then instead of printing those characters
  389.           printf() will print the next data item (data1, data2, data3,
  390.           etc...).  The way the data will be presented is determined by the
  391.           characters immediately following the percent sign (%).  There are
  392.           many such data formats, as described fully in the Registered
  393.           User's Manual (or any C programming manual), but here's few to
  394.           start with:
  395.             *%%  print a percentage sign
  396.             *%d  print a decimal integer
  397.             *%X  print a hexadecimal integer
  398.             *%c  print a character
  399.             *%f  print a floating-point value
  400.             *%E  print a floating-point value in scientific format
  401.             *%s  print a string
  402.  
  403.           There are also special characters that cause unique screen
  404.           behavior when they are printed, some of which are:
  405.             *\n  goto beginning of next line
  406.             *\t  tab
  407.             *\a  alarm: audible beep
  408.             *\r  carriage-return without a line feed
  409.             *\"  print the quote character
  410.             *\\  print a backslash
  411.  
  412.           Here are some example printf() statements:
  413.               printf("Hello world. This is my %dst Cmm program.\n",Count);
  414.               printf("%c %d %dlips",'I',8,2);
  415.               printf("%d decimal is the same as %X in hexadecimal",n,n);
  416.               printf("My name is: %s\n","Mary");
  417.  
  418. 2.9.2   getch() Syntax
  419.  
  420.           getch() (GET CHaracter) waits for any key to be pressed.  The
  421.           program stops executing at the getch() statement until a key is
  422.           pressed.  getch() is especially useful in Windows because once a
  423.           program is completed its windows will go away.  So getch() might
  424.           be placed at the end of the program to keep the screen visible
  425.           until a key is pressed.
  426.  
  427. 2.9.3   Using printf() and getch() to Learn Cmm
  428.  
  429.           You can now experiment with what you are learning by using the
  430.           printf() and getch() statements.
  431.  
  432.           If, during program execution, you want to know that you're about
  433.           to execute an exciting piece of code, then before those
  434.           interesting lines of code you may want to write:
  435.  
  436.               printf("Here comes the good stuff.  Press any key...");
  437.               getch();
  438.  
  439.           You can display values at any point in your program with a
  440.           printf() statement.  This short TEST.CMM program tests how "*="
  441.           works:
  442.  
  443.               // TEST.CMM - test the *= operator
  444.               var1 = 4;
  445.               var2 = 5;
  446.               printf("the numbers are %d and %d\n",var1,var2);
  447.               var1 *= 7;
  448.               var2 *= 7;
  449.               printf("after *= 7 the values are %d and %d\n",var1,var2);
  450.               getch();
  451.  
  452. 2.10. Bit Operators
  453.  
  454.           Cmm contains many operators for operating on the binary bits in a
  455.           byte or an integer.  If you're not familiar with hexadecimal
  456.           numbering (digits '0' to 'F'), you may want to refer to the CEnvi
  457.           Registered User's Manual.
  458.  
  459.               i = 0x146;
  460.  
  461.               //  "<<"  shift left: shift all bits left by value
  462.               //  "<<=" assignment shift left
  463.               i <<= 2;    // shift i (0x146) left 2, so i = 0x518
  464.  
  465.               //  ">>"  shift right: shift all bits right by value
  466.               //  ">>=" assignment shift right
  467.               i >>= 3;    // shift i (0x518) right 3, so i = 0xA3
  468.  
  469.               //  "&"   bitwise AND
  470.               //  "&="  assignment bitwise and
  471.               i &= 0x35;  // and i (0xA3) with 0x35 so i = 0x21
  472.  
  473.               //  "|"   bitwise OR
  474.               //  "|="  assignment bitwise OR
  475.               i |= 0xC5;    // OR i (0x21) with 0xC4 so i = 0xE5
  476.  
  477.               //  "^"   bitwise XOR: exlusive OR
  478.               //  "^="  assignment bitwise XOR
  479.               i ^= 0xF329 // XOR i (0xE5) with so i = 0xF3CC
  480.  
  481.               //  "~"   Bitwise complement: (turn 0 bits to 1, and 1 to 0)
  482.               i = ~i;     // complement i (0xF3CC) so i = 0xFFFF0C33 (OS/2)
  483.  
  484. 2.11. Logical Operators and Conditional Expressions
  485.  
  486.           A conditional expression is evaluated to be TRUE or FALSE, where
  487.           FALSE means zero, and TRUE means anything that is not FALSE
  488.           (i.e., not zero).  A variable or any other expression by itself
  489.           can be TRUE or FALSE (i.e., non-zero or zero).  With logic
  490.           operators, these expressions can be combined to make encompassing
  491.           TRUE/FALSE decisions.  The logic operators are:
  492.  
  493.             *"!"   NOT: opposite of decision
  494.               !TRUE               // FALSE
  495.               !FALSE              // TRUE
  496.               !('D')              // FALSE
  497.               !(5-5)              // TRUE
  498.  
  499.             *"&&"  AND: TRUE if and only if both expressions are true
  500.               TRUE && FALSE       // FALSE
  501.               TRUE && TRUE        // TRUE
  502.               0 && (foo+2)        // FALSE: (foo+2) is not evaluated
  503.               !(5-5) && 4         // TRUE
  504.  
  505.             *"||"  OR: TRUE if either expression is TRUE
  506.               TRUE || FALSE       // TRUE: doesn't even check FALSE
  507.               TRUE || (4+2)       // TRUE: (4+2) is not evaluated
  508.               FALSE || (4+2)      // TRUE: (4+2) is evaluated
  509.               FALSE || FALSE      // FALSE
  510.               0 || 0.345          // TRUE
  511.               !(5-3) || 4         // TRUE
  512.  
  513.             *"=="  EQUALITY: TRUE if both values equal, else FALSE
  514.               5 == 5              // TRUE
  515.               5 == 6              // FALSE
  516.  
  517.             *"!="  INEQUALITY: TRUE if both values not equal, else FALSE
  518.               5 != 5              // FALSE
  519.               5 != 6              // TRUE
  520.  
  521.             *"<"   LESS THAN
  522.               5 < 5               // FALSE
  523.               5 < 6               // TRUE
  524.  
  525.             *"<"   GREATER THAN
  526.               5 > 5               // FALSE
  527.               5 > 6               // FALSE
  528.               5 > -1              // TRUE
  529.  
  530.             *"<="  LESS THAN OR EQUAL TO
  531.               5 <= 5              // TRUE
  532.               5 <= 6              // TRUE
  533.               5 <= -1             // FALSE
  534.  
  535.             *">="  GREATER THAN OR EQUAL TO
  536.               5 >= 5              // TRUE
  537.               5 >= 6              // FALSE
  538.               5 >= -1             // TRUE
  539.  
  540. 2.12. Flow Decisions: Loops, Conditions, and Switches
  541.  
  542.           This section describes how Cmm statements can control the flow of
  543.           your program.  You'll notice code sections are often indented,
  544.           when blocks belong together; this makes the code much easier to
  545.           read.
  546.  
  547. 2.12.1  IF - Execute statement (or block) if conditional expression is TRUE
  548.  
  549.               if ( goo < 10 ) {
  550.                 printf("goo is smaller than 10\n");
  551.               }
  552.  
  553. 2.12.2  ELSE - Execute statement (or block) if IF block was not executed
  554.               if ( goo < 10 ) {
  555.                 printf("goo is smaller than 10\n");
  556.               } else {
  557.                 printf("goo is not smaller than 10\n");
  558.               }
  559.  
  560.           ELSE can also be combined with IF to find one in a series of
  561.           values:
  562.  
  563.               if ( goo < 10 ) {
  564.                 printf("goo is less than 10\n");
  565.                 if ( goo < 0 ) {
  566.                   printf("goo is negative; of course it's less than 10\n");
  567.                 }
  568.               } else if ( goo > 10 ) {
  569.                 printf("goo is greater than 10\n");
  570.               } else {
  571.                 printf("goo is 10\n");
  572.               }
  573.  
  574. 2.12.3  WHILE - Execute block while conditional expression is TRUE
  575.  
  576.               str = "WHO ARE YOU?";
  577.               while ( str[0] != 'A' ) {
  578.                 printf("%s\n",str);
  579.                 str++;
  580.               }
  581.               printf("%s\n",str);
  582.  
  583.           The output of the above code would be:
  584.               WHO ARE YOU?
  585.               HO ARE YOU?
  586.               O ARE YOU?
  587.                ARE YOU?
  588.               ARE YOU?
  589.  
  590. 2.12.4  DO ... WHILE - Execute block, and then test for conditional
  591.  
  592.           This is different from the WHILE statement in that the block is
  593.           executed at least once, before the condition is tested.
  594.  
  595.               do {
  596.                 value++;
  597.                 printf("value = %d\n",value);
  598.               } while( value < 100 );
  599.  
  600.           The code used to demonstrate the WHILE statement might be better
  601.           written this way to avoid the extra printf():
  602.  
  603.               str = "WHO ARE YOU?";
  604.               do {
  605.                 printf("%s\n",str);
  606.               } while ( str++[0] != 'A' );
  607.  
  608. 2.12.5  FOR - initialize, test conditional, then loop
  609.  
  610.           "for" is a combination of statements of this format:
  611.               for ( initialization; conditional; loop_expression )
  612.                 statement
  613.           The initialization is performed first.  Then the conditional is
  614.           tested.  If the conditional is TRUE (or if there is no
  615.           conditional expression) then statement is executed, and then the
  616.           loop_expression is executed, and so on back to testing the
  617.           conditional.  If the conditional is FALSE then the program
  618.           continues beyond statement.  The "for" statement is a shortcut
  619.           for this form of WHILE:
  620.               initialization;
  621.               while ( conditional ) {
  622.                 statement;
  623.                 loop_expression;
  624.               }
  625.  
  626.           The above code demonstrating the WHILE statement would be
  627.           rewritten this way if you preferred to use the FOR statement:
  628.  
  629.               for ( str = "WHO ARE YOU?"; str[0] != 'A'; str++ )
  630.                 printf("%s\n",str);
  631.               printf("%s\n",str);
  632.  
  633.  
  634. 2.12.6  BREAK and CONTINUE
  635.  
  636.           "break" terminates the nearest loop or case statement.
  637.  
  638.           "continue" jumps to the test condition in the nearest DO or WHILE
  639.           loop, and jumps to the loop_expression in the nearest FOR loop.
  640.  
  641. 2.12.7  SWITCH, CASE, and DEFAULT
  642.  
  643.           The SWITCH statement follows this format:
  644.  
  645.               switch( switch_expression ) {
  646.                 case exp1:  statement1
  647.                 case exp2:  statement2
  648.                 case exp3:  statement3
  649.                 case exp4:  statement4
  650.                 case exp5:  statement5
  651.                 .
  652.                 .
  653.                 .
  654.                 default: default_statement
  655.               }
  656.  
  657.           switch_expression is evaluated, and then it is compared to all of
  658.           the case expressions (expr1, expr2, expr3, etc...) until a match
  659.           is found (i.e., switch_expression == expr? ).  The statements
  660.           following that match are then executed until the end of the
  661.           switch block is reached or until a BREAK statement exits the
  662.           switch block.  If no match is found, the DEFAULT: statement is
  663.           executed if there is one.
  664.  
  665.           For example, this code handles the variable "key", which is
  666.           assumed to be the value of a key that was just pressed on the
  667.           keyboard:
  668.  
  669.               switch ( key ) {
  670.                 case '0':
  671.                 case '1':
  672.                 case '2':
  673.                 case '3':
  674.                 case '4':
  675.                 case '5':
  676.                 case '6':
  677.                 case '7':
  678.                 case '8':
  679.                 case '9:
  680.                   printf("A digit was pressed\n");
  681.                   break;
  682.                 case '\r';
  683.                   printf("You pressed RETURN\n");
  684.                 default:
  685.                   printf("I am not prepared for the key you pressed\n");
  686.                   break;
  687.               }
  688.  
  689. 2.12.8  GOTO and Labels
  690.  
  691.           You may jump to any location within a function block (see
  692.           functions) by using the GOTO statement.  The syntax is:
  693.               goto LABEL;
  694.           where LABEL is an identifier followed by a colon (:).
  695.  
  696.               if ( a < 0 ) {
  697.                 BadGoingsOn:      // this is a label
  698.                 printf("\aThe value for a is very bad.\n");
  699.                 abort();          // see function library for abort()
  700.               } else if ( 1000 < a )
  701.                 goto BadGoingsOn;
  702.  
  703.           GOTOs should be used sparingly, for they often make it difficult
  704.           to track program flow.
  705.  
  706. 2.13. Conditional Operator ?:
  707.  
  708.           The conditional operator is a strange-looking statement that is
  709.           simply a useful shortcut.  The syntax is this:
  710.  
  711.               test_expression ? expression_if_true : expression_if_false
  712.  
  713.           First, test_expression is evaluated.  If test_expression is
  714.           non-zero (TRUE) then expression_if_true is evaluated and the
  715.           value of the entire expression replaced by the value of
  716.           expression_if_true.  If test_expression is FALSE, then
  717.           expression_if_false is evaluated and the value of the entire
  718.           expression is that of expression_if_false.
  719.  
  720.           For example:
  721.               foo = ( 5 < 6 ) ? 100 : 200;  // foo is set to 100
  722.               printf("User's name is %s\n",NULL==name ? "unknown" : name);
  723.  
  724. 2.14. Functions
  725.  
  726.           Functions in Cmm can perform any action of any complexity, and
  727.           yet they are used in statements as easily as variables.  It is
  728.           because of the flexibility and simplicity of functions that Cmm
  729.           needs so few statements.  Any action can take place in a
  730.           function, and yet the function is treated by the calling code
  731.           simply as the data type that the function returns.
  732.  
  733. 2.14.1  Function definition
  734.  
  735.           A function takes a form such as this:
  736.  
  737.               FunctionName(Parameter1,Parameter2,Parameter3)
  738.               {
  739.                 statements...
  740.                 return result;
  741.               }
  742.  
  743.           where the function name is followed by a list of input parameters
  744.           in parentheses (there can be any number of input parameters and
  745.           they can be named with any variable names).
  746.  
  747.           A call is made to a function in this format:
  748.  
  749.               FunctionName(Value1,Value2,Value3)
  750.  
  751.           So any call to FunctionName will be result in the execution of
  752.           FunctionName() with the parameters passed, and then be equivalent
  753.           to whatever value FunctionName() returns.
  754.  
  755. 2.14.2  Function RETURN Statement
  756.  
  757.           The return statement causes a function to return to the code that
  758.           initially called the function.  The calling code will receive the
  759.           value that the function returned.  Here are function examples:
  760.  
  761.               foo(a,b)    // return a times b
  762.               {
  763.                 return( a * b );
  764.               }
  765.  
  766.               foo(a,b)    // return a times b
  767.               {
  768.                 return a * b;
  769.               }
  770.  
  771.               foo(a,b)    // return the minimum value of a and b
  772.               {
  773.                 if ( a < b )
  774.                   result = a;
  775.                 else
  776.                   result = b;
  777.                 return(result);
  778.               }
  779.  
  780.               foo(a,b)    // return a structure with members .min and .max
  781.               {           // for the smaller and larger of a and b
  782.                 if ( a < b ) {
  783.                   bounds.min = a;
  784.                   bounds.max = b; 
  785.                 } else {
  786.                   bounds.min = b;
  787.                   bounds.max = a;
  788.                 }
  789.                 return( bounds );
  790.               }
  791.  
  792.           If no value is returned, or if the end of the function block is
  793.           reached without a return statement, then no value is returned and
  794.           the function is a "void" type.  void functions return no value to
  795.           the calling code.  These examples demonstrate some void-returning
  796.           functions:
  797.  
  798.               foo(a,b)    // set a = b squared. No return value.
  799.               {
  800.                 a = b * b;
  801.                 return;
  802.               }
  803.  
  804.               foo(a,b)    // set a = b squared. No return value.
  805.               {
  806.                 a = b * b;
  807.               }
  808.  
  809. 2.14.3  Function Example
  810.  
  811.           The use of functions should gain clarity with this example.  This
  812.           code demonstrates a function that multiplies two integers
  813.           (although multiplying integers could more easily be performed
  814.           with the multiply (*) operator):
  815.  
  816.               num1 = 4;
  817.               num2 = 6;
  818.  
  819.               // use the standard method of multiplying numbers
  820.               printf("%d times %d is %d\n",num1,num2,num1*num2);
  821.  
  822.               // now call our function to do the same thing
  823.               printf("%d times %d is %d\n",num1,num2,Multiply(num1,num2));
  824.  
  825.                 // declare a function that multiplies two integers.  Notice
  826.                 // that the integers are defined as i and j, so that's how
  827.                 // they'll be called in this function, no matter what they
  828.                 // were named in the calling code.  This function will
  829.                 // return i added to itself j times.
  830.               Multiply(i,j)
  831.               {
  832.                 total = 0;
  833.                 for ( count = 0; count < j; count++ )
  834.                   total += i;
  835.                 return(total);  // caller will receive this value
  836.               }
  837.  
  838.           When executed, the above code will print:
  839.               4 times 6 is 24
  840.               4 times 6 is 24
  841.  
  842.           This example demonstrated several features of Cmm functions.
  843.           Notice that in calling printf() the parameter "num1*num2" is not
  844.           passed to printf, but the result of "num1*num2" is passed to
  845.           printf.  Likewise, "Multiply(num1,num2)" is not a parameter to
  846.           printf(); instead, printf receives the return value of Multiply()
  847.           as its parameter.
  848.  
  849. 2.14.4  Function Recursion
  850.  
  851.           When a function calls itself, or calls some other function that
  852.           calls itself, then it is known as a recursive function.
  853.           Recursion is permitted in Cmm, as it is in C.  Each call into a
  854.           function is independent of any other call to that function (see
  855.           section on variable scope).
  856.  
  857.           The following function, factor(), factors a number.  Factoring is
  858.           a natural candidate for recursion because it is a repetitive
  859.           process where the result of one factor is then itself factored
  860.           according to the same rules.
  861.  
  862.               factor(i)   // recursive function to print all factors of i,
  863.               {           // and return the number of factors in i
  864.                  if ( 2 <= i ) {
  865.                     for ( test = 2; test <= i; test++ ) {
  866.                        if ( 0 == (i % test) ) {
  867.                           // found a factor, so print this factor then call
  868.                           // factor() recursively to find the next factor
  869.                           printf(" %d",test);
  870.                           return( 1 + factor(i/test) );
  871.                        }
  872.                     }
  873.                  }
  874.                  // if this point was reached, then factor not found
  875.                  return( 0 );
  876.               }
  877.  
  878. 2.15. Variable Scope
  879.  
  880.           A variable in Cmm is either global or local.  A global variable
  881.           is one that is referenced outside of any function, making it
  882.           visible and accessible to all functions.  A local variable is one
  883.           that is only referenced inside of a function, and so it only has
  884.           meaning and value within the function that declares it.  Note
  885.           that two local variables in different functions are not the same
  886.           variable.  Also, each instance of a recursive function has its
  887.           own set of local variables.  In other words, a variable that is
  888.           not referenced outside of a function only has meaning (and that
  889.           meaning is unique) while the code for that function is executing.
  890.  
  891.           In the following sample code, "number" is the only global
  892.           variable, the two "result" variables in Quadruple() and Double()
  893.           are completely independent, and the "result" variable in one call
  894.           Double() is unique to each call to Double():
  895.  
  896.               number = Quadruple(3);
  897.  
  898.               Quadruple(i)
  899.               {
  900.                 result = Double(Double(i));
  901.                 return(result);
  902.               }
  903.  
  904.               Double(j)
  905.               {
  906.                 result = j + j;
  907.                 return(result);
  908.               }
  909.  
  910.           Note that variables that are all in uppercase letter are
  911.           considered global and refer to environment variables.  See the
  912.           chapter on CEnvi specifics for more on environment variables.
  913.  
  914. 2.16. #define
  915.  
  916.           "#define" is used to replace a token (a variable or a function
  917.           name) with other characters.  The structure is:
  918.               #define token replacement
  919.           This results in all subsequent occurrences of "token" to be
  920.           replaced with "replacement".  For example:
  921.               #define HI  "Hello world!"
  922.               printf(HI);
  923.           would result in the following output:
  924.               Hello world!
  925.           because HI was replaced with "Hello world!"
  926.  
  927.           A common use of #define is to define constant numeric or string
  928.           values that might possibly change, so that in the future only the
  929.           #define at the top of the file needs to be altered.  For
  930.           instance, if you write screen routines for a 25-line monitor, and
  931.           then later decide to make it a 50-line monitor, you're better off
  932.           altering
  933.               #define ROW_COUNT   25
  934.           to
  935.               #define ROW_COUNT   50
  936.           and using ROW_COUNT in your code (or ROW_COUNT-1, ROW_COUNT+2,
  937.           ROW_COUNT/2, etc...) than if you had to search for every instance
  938.           of the numbers 25, 24, 26, etc...
  939.  
  940.           CEnvi has a large default list of tokens that have already been
  941.           #define'd, such as TRUE, FALSE, and NULL.  More of these are
  942.           listed in the chapter on the Internal Function Library.
  943.  
  944. 2.17. #include
  945.  
  946.           Cmm code is executed from one stream of source code.  Sometimes
  947.           it is useful to break the program into different files or to
  948.           access commonly used code without recreating that code again and
  949.           again in every new program written.  This is what "#include" is
  950.           for: it allows code from another file to be included in a
  951.           program.
  952.  
  953.           The #include syntax is:
  954.  
  955.               #include <Name[,Ext[,Prefix[,BeginCode[,EndCode]]]]>
  956.               where:
  957.               Name - Name of the file to include
  958.               Ext - Extension name to add to Name if not already there
  959.               Prefix - Will only include code from Name on lines that begin
  960.                        with this string
  961.               BeginCode - Will start including code from Name following
  962.                           this line of text
  963.               EndCode - Will stop including code when this line is read
  964.  
  965.           The quote characters (' or ") may be used in place of < and >.
  966.           The only field that is required by Cmm is Name (this is the field
  967.           used in C's #include), which is the name of the file to include.
  968.           All other fields are optional, and can be left blank if unused.
  969.  
  970.           To include all of C:\CMM\LIB.cmm
  971.               #include <c:\CMM\LIB.cmm>
  972.           To include from dog.bat between the lines GOTO END and :END
  973.               #include 'dog,bat,,GOTO END,:END'
  974.           To include lots of little files into one big one program
  975.               #include <screen.cmm>
  976.               #include <keyboard.cmm>
  977.               #include <init.cmm>
  978.               #include <comm.cmm>
  979.  
  980. 2.18. Initialization
  981.  
  982.           All code that is outside of any function is part of the global
  983.           initialization function.  This code is executed first, before
  984.           calling any function (unless a function is called from this
  985.           initialization code).
  986.  
  987.           Any variables referenced in the initialization section are
  988.           global.
  989.  
  990. 2.19. main(ArgCount,ArgStrings)
  991.  
  992.           After the initialization has been performed, the main() function
  993.           is called and is given the argument input to the Cmm program.
  994.           The first parameter to main (ArgCount) is the number of arguments
  995.           provided to the program.  ArgStrings is an array of those input
  996.           arguments, which are always strings.  The first argument is
  997.           always the name of the source code, or of CEnvi.exe if there is
  998.           no source file.
  999.  
  1000.           The value returned from main() should be an integer, and is the
  1001.           exit code (ERRORLEVEL for DOS) returned to the operating system
  1002.           from your program (see also exit() in the internal library).
  1003.  
  1004.           This code file TEST.CMM:
  1005.               printf("I am initializing\n");
  1006.               main(argc,argv)
  1007.               {
  1008.                 printf("This program is called %s.\n",argv[0]);
  1009.                 printf("There are %d input arguments, as follows:\n",argc);
  1010.                 for ( i = 0; i < argc; i++ )
  1011.                   printf("\t%s\n",argv[i]);
  1012.                 return(0);
  1013.               }
  1014.               printf("still initializing\n");
  1015.           When executed in this way:
  1016.               cenvi test.cmm I am 4 "years old" today
  1017.           would result in this output:
  1018.               I am initializing
  1019.               still initializing
  1020.               This program is called test.CMM.
  1021.               There are 6 input arguments, as follows:
  1022.                       test.CMM
  1023.                       I
  1024.                       am
  1025.                       4
  1026.                       years old
  1027.                       today
  1028.           and would return 0 to the operating system.
  1029.  
  1030. -------------------------------- FILE LIST --------------------------------
  1031. The CEnvi Unregistered Shareware package includes the files in the
  1032. following list.  You are not permitted to upload or otherwise transfer
  1033. copies of any registered version of CEnvi that does not include all of the
  1034. files in this list.
  1035. *CENVI.EXE: CEnvi shareware executable for DOS, OS/2, or Windows.
  1036. *CENVI2PM.EXE: Gateway program, executed trasnparently by CEnvi, for access
  1037.   to PM-dependent system calls (OS/2 version only).
  1038. *CENVI.DOC: CEnvi Shareware Manual, Chapter 1: CEnvi Unregistered Shareware
  1039. *CMMTUTOR.DOC: CEnvi Shareware Manual, Chapter 2: Cmm Language Tutorial
  1040. *CMM_VS_C.DOC: CEnvi Shareware Manual, Chapter 3: Cmm versus C, for C
  1041.   Programmers
  1042. *CENVILIB.DOC: CEnvi Shareware Manual, Chapter 4: Function Library
  1043. *LICENSE.DOC: CEnvi Unregistered Shareware License Agreement
  1044. *README.DOC: Introductory file. Read this first for quick intallation.
  1045. *REGISTER.DOC: CEnvi registration form
  1046. *INSTALL.CMM: Cmm source file for installing this shareware version
  1047. * *.CMM, *.CMD, *.BAT, *.LIB: Many many sample programs using CEnvi.  See
  1048.   CENVI.DOC for a complete list.
  1049.  
  1050. ----------------------------- REGISTRATION -------------------------------
  1051. This is a shareware release.  Please register.  As a registered CEnvi user
  1052. you will receive:
  1053. *The latest version of CEnvi for all supported platforms (currently DOS,
  1054.   OS/2, and Windows).
  1055. *The CEnvi user's manual (almost 100 pages, including a description of the
  1056.   Cmm programming language, a tutorial for those who have never programmed,
  1057.   and descriptions and examples of the over 150 functions included in the
  1058.   CEnvi library).
  1059. *Free incremental electronic downloads for new versions of CEnvi for all
  1060.   supported operating systems.
  1061. *Unlimited support from Nombas and CEnvi/Cmm users through CompuServe
  1062.   (72212,1622), internet (bsn@world.std.com), the cenvi-cmm e-mail mailing
  1063.   list (cenvi-cmm@world.std.com), and the Nombas BBS
  1064.   (ATDT16173916595,,,,,44444).
  1065. *Access to the growing list of CEnvi utilities and libraries (some of which
  1066.   are included in this unregistered shareware package, and others are
  1067.   contributed by Nombas and CEnvi/Cmm users to the electronic locations
  1068.   described above).
  1069.  
  1070. There are three ways to register CEnvi version 1.008: 
  1071.  
  1072. ***************************************************************************
  1073. ********* REGISTRATION METHOD 1: CENVI MAIL-IN REGISTRATION FORM **********
  1074. ***************************************************************************
  1075. Please fill out and mail in this form, along with payment.
  1076.  
  1077. Where did you get CEnvi? ______________________________________________
  1078.  
  1079. Name: _________________________________________________________________
  1080.  
  1081. Company: ______________________________ Position: _____________________
  1082.  
  1083. Address: ______________________________________________________________
  1084.  
  1085. _______________________________________________________________________
  1086.  
  1087. ______________________________________________________________________
  1088.  
  1089. Country: _________________________   (add ZIP code if applicable)
  1090.  
  1091. Phone: ___________________________  EMail: ______________________________
  1092.  
  1093.           Diskette size: [  ] 3.5"   [  ] 5.25"
  1094.  
  1095. CEnvi Registered License & Manual.... Quantity _____ x $38.00 = $ _________
  1096. License fee for additional CEnvi users at
  1097. your organization (does not include additional
  1098. manual or diskettes)...Simultaneous-User Count _____ x $15.00 = $ _________
  1099. Additional CEnvi Manuals..............Quantity _____ x $10.00 = $ _________
  1100. Shipping outside USA, Canada, or Mexico  $4.00 ................ $ _________
  1101.                                                        Subtotal $ _________
  1102. Massachusetts residents please add 5% sales tax ............... $ _________
  1103.  
  1104.                                                           Total $ _________
  1105.  
  1106. Include a check or money order for this total, IN U.S. FUNDS AND DRAWN ON A
  1107. U.S. BANK, payable to Nombas, or supply the following credit card payment
  1108. information.  Credit cards orders will be processed through a distributor:
  1109. Custom Computer Systems of Medford, MA.
  1110.  
  1111. Credit card orders (circle one): MasterCard / Visa / American Express
  1112.  
  1113.                                  Discover / Carte Blanche / Diners Club
  1114.  
  1115.     Card Number _____________________________________  Expires ____________
  1116.  
  1117.     Exact name on card (print) ____________________________________________
  1118.  
  1119.     Signature (REQUIRED) __________________________________________________
  1120.  
  1121. Mail this form, along with payment or credit information, to:
  1122.                Nombas
  1123.                P.O. Box 875
  1124.                Medford, MA  02155   USA
  1125.  
  1126.  
  1127. ***************************************************************************
  1128. ******** REGISTRATION METHOD 2: COMPUSERVE ELECTRONIC REGISTRATION ********
  1129. ***************************************************************************
  1130. CompuServe members may register directly through the CompuServe
  1131. Registration Service.  To use this service enter GO SWREG at your CI$
  1132. prompt.  Registration ID is 1354 for CEnvi for DOS, 1355 for CEnvi for
  1133. OS/2, and 1356 for CEnvi for Windows (you only need to register ONE
  1134. version).  Nombas will immediately be informed of your registration, and
  1135. the CEnvi registration fee will automatically be added to your CompuServe
  1136. bill.
  1137.  
  1138.  
  1139. ***************************************************************************
  1140. ************ REGISTRATION METHOD 3: Public (software) Library *************
  1141. ***************************************************************************
  1142. CREDIT CARD ORDERS ONLY -
  1143.  
  1144. You can order with MC, Visa, Amex, or Discover from Public (software)
  1145. Library by calling 800-2424-PsL or 713-524-6394 or by FAX to 713-524-6398
  1146. or by CIS Email to 71355,470. You can also mail credit card orders to PsL
  1147. at P.O.Box 35705, Houston, TX 77235-5705.
  1148.  
  1149. THE ABOVE NUMBERS ARE FOR ORDERS ONLY.
  1150.  
  1151. Any questions about the status of the shipment of the order, refunds,
  1152. registration options, product details, technical support, volume discounts,
  1153. dealer pricing, site licenses, etc, must be directed to Nombas (see phone
  1154. number and addresses below).
  1155.  
  1156. To insure that you get the latest version, PsL will notify Nombas the day
  1157. of your order and we will ship the product directly to you.
  1158.  
  1159. CEnvi (all versions) is PsL product #11069.  Prices (including shipping and
  1160. handling) are: $42 US/Canada and $45 overseas.
  1161.  
  1162.  
  1163. ***************************************************************************
  1164. Thank you for trying this shareware copy of CEnvi.  Mail inquires and other
  1165. correspondences to:
  1166.      Nombas
  1167.      P.O. Box 875
  1168.      Medford, MA  02155   USA
  1169.  
  1170. Nombas may also be contacted at:
  1171.      Phone: (617)391-6595
  1172.      Internet: bsn@world.std.com
  1173.      CompuServe: 72212,1622
  1174.      BBS: (617)391-6595 ext. 44 (e.g., ATDT16173916595,,,,,44444)
  1175.